'''
Descripttion: 
version: 
Author: jinqian
Date: 2022-05-02 10:51:34
LastEditors: jinqian
LastEditTime: 2022-05-02 17:05:51
'''


import docker
from app.utils.errors import RemoteNodeNotSetDockerException, CurrentHostNotSetSwarmException, JoinSwarmErrorException, GetTokenErrorException, DockerisNotStartException
import app.controller.DockerCtl


def GetRemoteDockerClient(ip: str, port: str):
    baseUrl = ip + ":"+port
    Client = docker.APIClient(base_url=baseUrl)
    if Client is None:
        raise RemoteNodeNotSetDockerException()

    return Client


def GetCurrentDockerClient():
    Client = docker.APIClient(base_url='unix://var/run/docker.sock')
    if Client is None:
        raise DockerisNotStartException()

    return Client


def GetDockerClient():
    Client = docker.DockerClient(base_url='unix://var/run/docker.sock')
    if Client is None:
        raise DockerisNotStartException()

    return Client


def NodeJoinSwarm(ClientRemote: docker.APIClient):
    WorkerToken = GetWorkerToken(ClientRemote)
    isJoin = ClientRemote.join_swarm(
        remote_addrs=app.config.SwarmConfig.ManagerHost, join_token=WorkerToken)
    if isJoin == False:
        raise JoinSwarmErrorException()

    return isJoin


def GetSwarmInspect(Client: docker.APIClient):
    Inspect = Client.inspect_swarm()
    if Inspect is None:
        raise CurrentHostNotSetSwarmException()

    return Inspect


def GetWorkerToken(Client: docker.APIClient):
    SwarmInspect = GetSwarmInspect(Client)
    WorkerToken = SwarmInspect['JoinTokens']['Worker']
    if WorkerToken is None:
        raise GetTokenErrorException()

    return WorkerToken


def GetManagerToken(Client: docker.APIClient):
    SwarmInspect = GetSwarmInspect(Client)
    ManagerToken = SwarmInspect['JoinTokens']['Manager']
    if ManagerToken is None:
        raise GetTokenErrorException()

    return ManagerToken


def InitSwarmCurrentHost(Client: docker.APIClient):

    managerhost = app.config.SwarmConfig.ManagerHost[0]
    Client.init_swarm(managerhost, managerhost)
    return True


def GetNodeList():
    Client = GetCurrentDockerClient()
    Nodes = Client.nodes()
    Res = []
    for node in Nodes:
        if node['Status']['State'] == 'ready':
            # Res.append(node)
            tarnode = app.controller.DockerCtl.node(
                id=node['ID'], Hostname=node['Description']['Hostname'], CreatedAt=node['CreatedAt'], UpdatedAt=node['UpdatedAt'], Status=node['Status']['State'], Addr=node['Status']['Addr'])
            Res.append(tarnode)
    return Res


def GetnodeNamebyID(mainNodeId):
    Client = GetDockerClient()
    ins = Client.api.inspect_node(mainNodeId)
    return ins['Status']['Addr']


def GetServiceList():
    Client = GetDockerClient()
    Services = Client.services.list()
    Res = []
    for service in Services:
        tasks = service.tasks()
        id = service.short_id
        mainNodeName = "error"
        time = ""
        for task in tasks:
            if task['Status']['State'] == 'running':
                mainNodeID = task['NodeID']
                mainNodeName = GetnodeNamebyID(mainNodeID)
                time = task['CreatedAt']
                break
        if mainNodeName == "error":
            continue
        mainMemory = 0
        slavememory = 0
        size = len(tasks)
        servicename = service.name

        tarservice = app.controller.DockerCtl.service(
            mainNode=mainNodeName, size=size, mainMemory=mainMemory, slaveMemory=slavememory, id=id, servicename=servicename, time=time)
        Res.append(tarservice)
    return Res


def GetTaskList():
    Client = GetCurrentDockerClient()
    Tasks = Client.tasks()
    return Tasks
